﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Ubuntwin.Properties;

namespace Ubuntwin
{
    public partial class Form1 : Form
    {
        static readonly string BashPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "bash.exe");

        public List<Process> Processes = new List<Process>();

        public Form1()
        {
            InitializeComponent();
            Text = Application.ProductName;
            Icon = Resources.start_here_ubuntu;
            appVersionLabel.Text = $"Version {Assembly.GetExecutingAssembly().GetName().Version}";
            FormClosing += Form1_FormClosing;

            notifyIcon1.Text = Application.ProductName;
            notifyIcon1.Icon = Resources.start_here_ubuntu;
            notifyIcon1.Visible = true;
            notifyIcon1.MouseDoubleClick += NotifyIcon1_MouseClick;
            notifyIcon1.ContextMenuStrip = new ContextMenuStrip();
            notifyIcon1.ContextMenuStrip.Items.AddRange(new ToolStripItem[]
            {
                new ToolStripMenuItem("Bash", null, (s,e) => Bash()),
                new ToolStripMenuItem("Terminator", null, (s,e) => ExecWSL("terminator", true)),
                new ToolStripMenuItem("Sublime", null, (s,e) => ExecWSL("subl", true)),
                // TODO: Figure out why pkexec doesn't work.  Seems to be a WSL issue. gksu has a different problem.
                //new ToolStripMenuItem("Synaptic", null, (s,e) => ExecWSL("pkexec /usr/sbin/synaptic", true)),
                new ToolStripSeparator(),
                new ToolStripMenuItem("Processes", null, (s,e) => { tabControl1.SelectedTab=tabPageProcesses; Show(); BringToFront(); }),
                new ToolStripMenuItem("About", null, (s,e) => { tabControl1.SelectedTab=tabPageAbout; Show(); BringToFront(); }),
                new ToolStripSeparator(),
                new ToolStripMenuItem("Quit", null, (s,e) => { Application.Exit(); }),
            });
            Uri installUri = new Uri(AppDomain.CurrentDomain.BaseDirectory);
            
            string installPath = Uri.UnescapeDataString(installUri.AbsolutePath);
            string installDriveLetter = Path.GetPathRoot(installPath).Substring(0, 1).ToLowerInvariant();
            installPath = installPath.Substring(Path.GetPathRoot(installPath).Length);
            string initScriptPath = $"/mnt/{installDriveLetter}/{installPath}ubuntwin_init.sh";
            Debug.WriteLine(initScriptPath);
            var process = CreateWSLProcess($"-ilc \"'{initScriptPath}'\"", true);
            process.Exited += (s, e) => Processes.Remove(s as Process);
            process.EnableRaisingEvents = true;
            process.Start();
            Processes.Add(process);
        }

        public void ExecWSL(string command, bool createNoWindow = false)
        {
            var process = ExecWSLProcess(command, createNoWindow);
            process.Exited += (s, e) => Processes.Remove(s as Process);
            process.EnableRaisingEvents = true;
            process.Start();
            Processes.Add(process);
        }

        public void Bash()
        {
            var process = CreateWSLProcess();
            process.Exited += (s, e) => Processes.Remove(s as Process);
            process.EnableRaisingEvents = true;
            process.Start();
            Processes.Add(process);
        }

        public static Process ExecWSLProcess(string command, bool createNoWindow = false)
        {
            return CreateWSLProcess($"-ilc \"exec {command} </dev/null &>/dev/null\"", createNoWindow);
        }
        public static Process CreateWSLProcess(string command = null, bool createNoWindow = false)
        {
            Debug.WriteLine(BashPath);
            var bash = new Process();
            bash.StartInfo = new ProcessStartInfo()
            {
                FileName = BashPath,
                Arguments = command,
                CreateNoWindow = createNoWindow,
                UseShellExecute = false,
            };
            return bash;
        }

        protected override void OnLoad(EventArgs e)
        {
            Visible = false;
            ShowInTaskbar = false;
            base.OnLoad(e);
        }

        private void NotifyIcon1_MouseClick(object sender, MouseEventArgs e)
        {
            Show();
            BringToFront();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                Hide();
            }
            else
            {
                foreach (var proc in Processes) if (!proc.HasExited) proc.Kill();
            }
        }
    }
}
